﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using App1AppHandler;
using System.Drawing;
using Reborn_WorldServer;

namespace Reborn_Server.App1AppHandler
{
    public class Spell_Flood : Buff
    {
        private TileDataManager tileManager = new TileDataManager();

        public Spell_Flood()
        {
            minutesLeft = 10;
        }

        public override bool hasCustomTarget(SpellIcon sIcon)
        {
            return true;
        }

        public override bool hasValidTarget(SpellIcon sIcon, Creature creature, List<Point> hiddenList)
        {
            if (creature.buffManager.GetBuffByStackType(sIcon.StackType) == null && creature.HP < creature.MaxHP * .70)
                return true;

            return false;
        }

        int castMapId;
        int castInstance;

        public void Cast(CreatureBase myCreatureBase, int CastLevel, long CreatureGUID)
        {
            CreatureGUID = myCreatureBase.CreatureID;
            castMapId = myCreatureBase.MapID;
            castInstance = myCreatureBase.Instance;

            List<MapItem> MapItemsWithin12;
            if (base.InitializeCast(myCreatureBase, CastLevel, CreatureGUID, true, out MapItemsWithin12) == false)
                return;

            List<Character> charactersToUpdate = new List<Character>();
            Map map = Managers.GameHandler.GetMap(myCreatureBase.MapID, myCreatureBase.Instance);
            foreach (MapItem mapItem in map.MapItems)
            {
                if (mapItem.TerrainType != "Water" && mapItem.allowAOE == true && mapItem.Transparent == true && mapItem.Motion > 0)
                {
                    tileManager.recordAndModifyTile(mapItem);
                }
                
                foreach (CreatureBase creatureBase in mapItem.CreaturesBases)
                {
                    if (creatureBase is Character)
                        charactersToUpdate.Add((Character)creatureBase);
                }
            }

            foreach (Character character in charactersToUpdate)
            {
                character.SetPosition(character.currentMapItem);
                character.AddMapItems(character.currentMapItem.mapItemsWithin4, true);
            }

            TargetCreatureBase.buffManager.UpdateBuffs();

            spellTimer.Start();
        }

        public override void RemoveSpell(bool updateBuffs, bool sendMessage)
        {
            base.RemoveSpell(updateBuffs, sendMessage);

            LockItem lockItem = Managers.GameHandler.GetLockItem(castMapId, castInstance);
            lock (lockItem.LockObj)
            {
                tileManager.restoreMapItems();

                List<Character> charactersToUpdate = new List<Character>();
                List<Creature> creaturesToDespawn = new List<Creature>();

                Map map = Managers.GameHandler.GetMap(castMapId, castInstance);
                foreach (MapItem mapItem in map.MapItems)
                {
                    foreach (CreatureBase creatureBase in mapItem.CreaturesBases)
                    {
                        if (creatureBase is Character)
                            charactersToUpdate.Add((Character)creatureBase);

                        if (creatureBase is Creature)
                        {
                            Creature creature = (Creature)creatureBase;
                            if (mapItem.TerrainType != "Water" && creatureBase.Land == false)
                                creaturesToDespawn.Add(creature);
                        }
                    }
                }

                foreach (Creature creature in creaturesToDespawn)
                {
                    creature.currentMapItem.CreaturesBases.Remove(creature);

                    Map map2 = Managers.GameHandler.GetMap(creature.StartMapID, castInstance);
                    MapItem mapitem = map2.GetMapItem(creature.StartMapX, creature.StartMapY);

                    creature.SetPosition(mapitem);
                    mapitem.CreaturesBases.Add(creature);
                }

                foreach (Character character in charactersToUpdate)
                {
                    character.SetPosition(character.currentMapItem);
                    character.AddMapItems(character.currentMapItem.mapItemsWithin4, true);
                }

                
            }
        }
    }
    class TileData
    {
        private int mapX;
        private int mapY;
        public int motion;

        public string groundUrl;
        public string terrainUrl;
        public string type;

        public TileData(MapItem mapItem)
        {
            mapX = mapItem.MapX;
            mapY = mapItem.MapY;
            motion = mapItem.Motion;
            groundUrl = mapItem.ColorUrl;
            terrainUrl = mapItem.TerrainUrl;
            type = mapItem.TerrainType;
        }
    }
    class TileDataManager
    {
        private List<TileData> effectedOrigionalData = new List<TileData>();
        private List<MapItem> effectedMapItems = new List<MapItem>();

        public void recordAndModifyTile(MapItem mapItem)
        {
            effectedOrigionalData.Add(new TileData(mapItem));

            mapItem.Motion = 2;
            mapItem.TerrainType = "Water";
            mapItem.ColorUrl = "Water";
            mapItem.TerrainUrl = "";
            effectedMapItems.Add(mapItem);
        }

        public void restoreMapItems()
        {
            while (effectedMapItems.Count > 0)
            {
                MapItem mapItem = effectedMapItems[0];
                TileData originData = effectedOrigionalData[0];

                mapItem.Motion = originData.motion;
                mapItem.ColorUrl = originData.groundUrl;
                mapItem.TerrainType = originData.type;
                mapItem.TerrainUrl = originData.terrainUrl;

                effectedMapItems.RemoveAt(0);
                effectedOrigionalData.RemoveAt(0);
            }
        }
    }
}
